/*
*   NOTES:
*       * Get srand value from user input, ie how long it takes to press START button
*           at start screen
*       * Mode3: gfx2gba -fsrc -c32k filename.bmp
*       * Mode4: gfx2gba -fsrc -pmode4.pal filename.bmp
*/

// Function header
////////////////////////////////////////////////////////////
// Function: FUNCTION NAME
// DESCRIPTION
////////////////////////////////////////////////////////////

#ifndef GLOBALS_H
#define GLOBALS_H

#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "helper_functions.h"


////////////////////////////////////////////////////////////
// sprite_handler defines
////////////////////////////////////////////////////////////

#define SpriteMem ((unsigned short*)0x7000000)
//Sprite Image data
#define SpriteData ((unsigned short*) 0x6010000)
//Sprite Palette
#define SpritePal ((unsigned short*) 0x5000200)
//other constants
#define OBJ_MAP_2D 0x0
#define OBJ_MAP_1D 0x40
#define OBJ_ENABLE 0x1000

//attribute0 stuff
#define ROTATION_FLAG       0x100
#define SIZE_DOUBLE         0x200
#define MODE_NORMAL         0x0
#define MODE_TRANSPERANT    0x400
#define MODE_WINDOWED       0x800
#define MOSAIC              0x1000
#define COLOR_16            0x0000
#define COLOR_256           0x2000
#define SQUARE              0x0
#define TALL                0x8000
#define WIDE                0x4000

//attribute1 stuff
#define ROTDATA(n)          ((n) << 9)
#define HORIZONTAL_FLIP     0x1000
#define VERTICAL_FLIP       0x2000
#define SIZE_8              0x0
#define SIZE_16             0x4000
#define SIZE_32             0x8000
#define SIZE_64             0xC000

//attribute2 stuff
#define PRIORITY(n)     ((n) << 10)
#define PALETTE(n)      ((n) << 12)


////////////////////////////////////////////////////////////
// general defines
////////////////////////////////////////////////////////////

#define REG_DMA3SAD *(volatile unsigned int*)0x40000D4
#define REG_DMA3DAD *(volatile unsigned int*)0x40000D8
#define REG_DMA3CNT *(volatile unsigned int*)0x40000DC
#define DMA_ENABLE 0x80000000
#define DMA_TIMING_IMMEDIATE 0x00000000
#define DMA_16 0x00000000
#define DMA_32 0x04000000
#define DMA_32NOW (DMA_ENABLE | DMA_TIMING_IMMEDIATE | DMA_32)
#define DMA_16NOW (DMA_ENABLE | DMA_TIMING_IMMEDIATE | DMA_16)

void DMAFastCopy(void* source, void* dest, unsigned int count,
    unsigned int mode)
{
    if (mode == DMA_16NOW || mode == DMA_32NOW)
    {
    	REG_DMA3SAD = (unsigned int)source;
        REG_DMA3DAD = (unsigned int)dest;
        REG_DMA3CNT = count | mode;
    }
}

/* Drawing Pointers and Modes and Such */

#define VBUFFERADDR 0x6000000
#define REG_DISPCNT *(unsigned short*)0x4000000

#define SetMode(mode) REG_DISPCNT=(mode)

#define MODE_3 0x3
#define MODE_4 0x4

unsigned short * videoBuffer = (unsigned short * )VBUFFERADDR;
unsigned short* paletteMem = (unsigned short*)0x5000000;
unsigned short* FrontBuffer = (unsigned short*)0x6000000;
unsigned short* BackBuffer = (unsigned short*)0x600A000;

#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 160

#define BACKBUFFER 0x10

void SetPalette( unsigned short const * palette )
{
    int x;
    // memcpy( paletteMem, palette, sizeof( unsigned short ) * 256 );
    for(x = 0; x < 256; x++)
	{
		paletteMem[x] = palette[x];
	}
}

// SwapBuffers
void FlipPage(void)	
{
	if(REG_DISPCNT & BACKBUFFER)
	{
		REG_DISPCNT &= ~BACKBUFFER;
		videoBuffer = BackBuffer;
    }
    else
    {
		REG_DISPCNT |= BACKBUFFER;
		videoBuffer = FrontBuffer;
	}
}

volatile unsigned short* ScanlineCounter =
    (volatile unsigned short*)0x4000006;

/*
void WaitVBlank(void)
{
    while(*ScanlineCounter < 160);
}
*/

// vertical refresh register
#define REG_DISPSTAT *(volatile unsigned short*)0x4000004

// wait for vertical refresh
void WaitVBlank(void)
{
	while((REG_DISPSTAT & 1));
}

#endif
